/*
 * Ext GWT - Ext for GWT
 * Copyright(c) 2007-2009, Ext JS, LLC.
 * licensing@extjs.com
 *
 * http://extjs.com/license
 */
package web.app.client.ui;

import web.app.client.security.AuthEvents;
import web.app.client.security.User;

import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.event.EventType;
import com.extjs.gxt.ui.client.event.KeyListener;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.mvc.AppEvent;
import com.extjs.gxt.ui.client.mvc.Controller;
import com.extjs.gxt.ui.client.mvc.Dispatcher;
import com.extjs.gxt.ui.client.mvc.View;
import com.extjs.gxt.ui.client.util.IconHelper;
import com.extjs.gxt.ui.client.widget.Dialog;
import com.extjs.gxt.ui.client.widget.Status;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.layout.FormLayout;
import com.extjs.gxt.ui.client.widget.toolbar.FillToolItem;

public class LoginView extends View {

	public static final EventType LoginClicked = new EventType(); 
	
	
	protected Dialog dialog;
	public TextField<String> userName;
	public TextField<String> password;
	protected Button reset;
	protected Button login;
	protected Status status;

	protected String authFailMessage = "authorization failed";
	protected String authRequestingMessage = "authorizing";

	public LoginView(Controller controller) {
		super(controller);

		dialog = new Dialog();
		dialog.setClosable(false);
        dialog.setHeading("Web Application Login");
        
		FormLayout layout = new FormLayout();
		layout.setLabelWidth(90);
		layout.setDefaultWidth(155);
		dialog.setLayout(layout);

		dialog.setButtonAlign(HorizontalAlignment.LEFT);
		dialog.setButtons("");
		dialog.setIcon(IconHelper.createStyle("user"));
		dialog.setModal(true);
		dialog.setBodyBorder(true);
		dialog.setBodyStyle("padding: 8px;background: none");
		dialog.setWidth(300);
		dialog.setResizable(false);

		KeyListener keyListener = new KeyListener() {
			@Override
			public void componentKeyUp(ComponentEvent event) {
				validate();
			}

		};

		userName = new TextField<String>();
		userName.setMinLength(4);
		userName.setFieldLabel("Username");
		userName.addKeyListener(keyListener);
		dialog.add(userName);

		password = new TextField<String>();
		password.setMinLength(4);
		password.setPassword(true);
		password.setFieldLabel("Password");
		password.addKeyListener(keyListener);
		dialog.add(password);

		dialog.setFocusWidget(userName);

		createButtons();
	}

	protected void createButtons() {
		status = new Status();
		status.setBusy("please wait...");
		status.hide();
		status.setAutoWidth(true);
		dialog.getButtonBar().add(status);

		dialog.getButtonBar().add(new FillToolItem());

		reset = new Button("Reset");
		reset.addSelectionListener(new SelectionListener<ButtonEvent>() {
			public void componentSelected(ButtonEvent ce) {
				userName.reset();
				password.reset();
				validate();
				userName.focus();
			}

		});

		login = new Button("Login");
		login.disable();
		login.addSelectionListener(new SelectionListener<ButtonEvent>() {
			public void componentSelected(ButtonEvent ce) {
				authRequest();
			}
		});

		dialog.addButton(reset);
		dialog.addButton(login);
	}

	protected void authRequest() {
		status.setBusy(authRequestingMessage);
		status.show();
		dialog.getButtonBar().disable();
		
		AppEvent evt = new AppEvent(AuthEvents.AuthRequested);
		evt.setData(User.USERNAME, userName.getValue());
		evt.setData(User.PASSWORD, password.getValue());
		Dispatcher.forwardEvent(evt);
		
		fireEvent( evt );
	}

	protected void onAuthFail() {
		status.setText(authFailMessage);
		dialog.getButtonBar().enable();
	}

	protected void onAuthSuccess() {
		dialog.hide();
	}

	protected boolean hasValue(TextField<String> field) {
		return field.getValue() != null && field.getValue().length() > 0;
	}

	protected void validate() {
		login.setEnabled(hasValue(userName) && hasValue(password)
				&& password.getValue().length() > 3);
	}

	@Override
	protected void handleEvent(AppEvent event) {
		EventType t = event.getType();
		if (t == AuthEvents.AuthDenied) {
			onAuthFail();
		} else if (t == AuthEvents.AuthSuccess) {
			onAuthSuccess();
		}
	}
	
	public void show(){
		dialog.show();
	}

}
